"""
TabPool 完整功能演示示例
"""
import time
import threading
import random
from tab_pool import TabPool, TabPoolManager
from DrissionPage import ChromiumOptions


def example1_basic_usage():
    """示例1: 基础用法演示"""
    print("=" * 50)
    print("示例1: TabPool 基础用法")
    print("=" * 50)
    
    with TabPool(max_tabs=2) as pool:
        print("✅ 创建了最大2个Tab的池")
        
        # 手动获取和归还
        print("\n--- 手动获取和归还Tab ---")
        tab1 = pool.get_tab()
        print(f"获取Tab: {tab1.tab_id}")
        tab1.get('https://www.baidu.com')
        print(f"访问百度: {tab1.title}")
        pool.return_tab(tab1)
        print("归还Tab")
        
        # 上下文管理器方式
        print("\n--- 上下文管理器方式 ---")
        with pool.acquire_tab() as tab:
            print(f"自动获取Tab: {tab.tab_id}")
            tab.get('https://www.bing.com')
            print(f"访问必应: {tab.title}")
        print("自动归还Tab")


def example2_concurrent_tasks():
    """示例2: 并发任务演示"""
    print("\n" + "=" * 50)
    print("示例2: 并发任务处理")
    print("=" * 50)
    
    def search_task(pool, keyword, task_id):
        """搜索任务"""
        start_time = time.time()
        print(f"🔍 任务{task_id}: 等待获取Tab...")
        
        with pool.acquire_tab(timeout=30) as tab:
            print(f"✅ 任务{task_id}: 获得Tab {tab.tab_id}, 搜索 '{keyword}'")
            
            # 访问百度
            tab.get('https://www.baidu.com')
            
            # 搜索关键词
            search_box = tab.ele('#kw')
            if search_box:
                search_box.input(keyword, clear=True)
                search_btn = tab.ele('#chat-submit-button')
                if search_btn:
                    search_btn.click()
                    time.sleep(2)
                    
                    # 获取结果
                    results = tab.eles('.t a')
                    elapsed = time.time() - start_time
                    print(f"📊 任务{task_id}: '{keyword}' 找到 {len(results)} 个结果 (耗时: {elapsed:.1f}s)")
            
            # 模拟处理时间
            time.sleep(random.uniform(1, 3))
    
    # 创建Tab池 (只有2个Tab)
    with TabPool(max_tabs=2) as pool:
        keywords = ['Python爬虫', 'DrissionPage', 'Web自动化', 'Selenium', 'JavaScript']
        
        print(f"🚀 启动 {len(keywords)} 个搜索任务，但只有2个Tab可用")
        
        threads = []
        for i, keyword in enumerate(keywords):
            thread = threading.Thread(target=search_task, args=(pool, keyword, i+1))
            threads.append(thread)
            thread.start()
            time.sleep(0.2)  # 错开启动时间
        
        # 等待所有任务完成
        for thread in threads:
            thread.join()
        
        print("🎉 所有搜索任务完成")


def example3_timeout_handling():
    """示例3: 超时处理演示"""
    print("\n" + "=" * 50)
    print("示例3: 超时处理机制")
    print("=" * 50)
    
    def long_task(pool, task_id, duration):
        """长时间任务"""
        try:
            with pool.acquire_tab(timeout=5) as tab:
                print(f"⏰ 任务{task_id}: 开始执行，预计耗时 {duration}s")
                tab.get('https://www.baidu.com')
                time.sleep(duration)
                print(f"✅ 任务{task_id}: 执行完成")
        except TimeoutError:
            print(f"❌ 任务{task_id}: 获取Tab超时 (5秒)")
        except Exception as e:
            print(f"❌ 任务{task_id}: 执行出错 - {e}")
    
    # 只创建1个Tab的池
    with TabPool(max_tabs=1) as pool:
        print("创建只有1个Tab的池，演示超时机制")
        
        # 启动多个任务，有些会超时
        tasks = [
            (1, 3),  # 任务1: 3秒
            (2, 2),  # 任务2: 2秒 (会超时)
            (3, 1),  # 任务3: 1秒 (会超时)
        ]
        
        threads = []
        for task_id, duration in tasks:
            thread = threading.Thread(target=long_task, args=(pool, task_id, duration))
            threads.append(thread)
            thread.start()
        
        for thread in threads:
            thread.join()


def example4_custom_browser_options():
    """示例4: 自定义浏览器选项"""
    print("\n" + "=" * 50)
    print("示例4: 自定义浏览器配置")
    print("=" * 50)
    
    # 自定义浏览器选项
    co = ChromiumOptions()
    co.set_timeouts(base=10, page_load=60)
    co.set_argument('--start-maximized')
    # co.headless()  # 取消注释启用无头模式
    co.set_pref('profile.default_content_settings.popups', 0)
    
    print("🔧 使用自定义浏览器配置:")
    print("   - 最大化窗口")
    print("   - 禁用弹窗")
    print("   - 自定义超时设置")
    
    with TabPool(max_tabs=2, browser_options=co) as pool:
        sites = [
            ('https://www.baidu.com', '百度'),
            ('https://www.bing.com', '必应'),
        ]
        
        for url, name in sites:
            with pool.acquire_tab() as tab:
                print(f"🌐 访问 {name}: {url}")
                tab.get(url)
                print(f"📄 页面标题: {tab.title}")
                time.sleep(1)


def example5_tab_pool_manager():
    """示例5: TabPoolManager 高级用法"""
    print("\n" + "=" * 50)
    print("示例5: TabPoolManager 高级管理")
    print("=" * 50)
    
    def crawl_news(tab, site_name, url):
        """爬取新闻标题"""
        print(f"📰 开始爬取 {site_name}")
        tab.get(url)
        
        # 根据不同网站获取标题
        titles = []
        if 'baidu' in url:
            # 百度热搜
            elements = tab.eles('.title-content-title')[:5]
            titles = [ele.text for ele in elements if ele.text]
        elif 'bing' in url:
            # 必应搜索建议
            tab.ele('#sb_form_q').input('热点新闻')
            time.sleep(1)
            elements = tab.eles('.sa_sg')[:3]
            titles = [ele.text for ele in elements if ele.text]
        
        print(f"📊 {site_name} 获取到 {len(titles)} 条标题")
        for i, title in enumerate(titles, 1):
            print(f"   {i}. {title}")
        
        return titles
    
    # 使用 TabPoolManager
    manager = TabPoolManager(max_tabs=2)
    
    news_sites = [
        ('百度热搜', 'https://www.baidu.com'),
        ('必应搜索', 'https://www.bing.com'),
        ('360搜索', 'https://www.so.com'),
    ]
    
    print(f"🚀 提交 {len(news_sites)} 个爬取任务")
    
    # 提交所有任务
    for site_name, url in news_sites:
        manager.submit_task(crawl_news, site_name, url)
    
    print("⏳ 等待所有任务完成...")
    manager.wait_all_tasks()
    print("🎉 所有爬取任务完成")
    
    manager.close()


def example6_error_handling():
    """示例6: 错误处理和恢复"""
    print("\n" + "=" * 50)
    print("示例6: 错误处理机制")
    print("=" * 50)
    
    def risky_task(pool, task_id, should_fail=False):
        """可能出错的任务"""
        try:
            with pool.acquire_tab() as tab:
                print(f"🎲 任务{task_id}: 开始执行")
                
                if should_fail:
                    # 模拟访问错误的URL
                    tab.get('https://invalid-url-that-does-not-exist.com')
                else:
                    tab.get('https://www.baidu.com')
                    print(f"✅ 任务{task_id}: 成功访问 - {tab.title}")
                
        except Exception as e:
            print(f"❌ 任务{task_id}: 执行失败 - {str(e)[:50]}...")
            # Tab会自动归还到池中
    
    with TabPool(max_tabs=2) as pool:
        print("🧪 测试错误处理机制")
        
        # 混合正常和异常任务
        tasks = [
            (1, False),  # 正常任务
            (2, True),   # 异常任务
            (3, False),  # 正常任务
            (4, True),   # 异常任务
        ]
        
        threads = []
        for task_id, should_fail in tasks:
            thread = threading.Thread(target=risky_task, args=(pool, task_id, should_fail))
            threads.append(thread)
            thread.start()
        
        for thread in threads:
            thread.join()
        
        print("🔄 即使有任务失败，Tab池仍然正常工作")


def example7_performance_comparison():
    """示例7: 性能对比演示"""
    print("\n" + "=" * 50)
    print("示例7: 性能对比 (Tab池 vs 传统方式)")
    print("=" * 50)
    
    urls = [
        'https://www.baidu.com',
        'https://www.bing.com',
        'https://www.so.com',
        'https://www.baidu.com',
        'https://www.bing.com',
        'https://www.so.com',
        'https://www.baidu.com',
        'https://www.bing.com',
        'https://www.so.com',
        'https://www.baidu.com',
        'https://www.bing.com',
        'https://www.so.com',
    ]
    
    # 方式1: 使用Tab池
    print("🚀 方式1: 使用Tab池并发访问")
    start_time = time.time()
    
    def visit_with_pool(pool, url, task_id):
        with pool.acquire_tab() as tab:
            tab.get(url)
            tab.wait.doc_loaded()
            print(f"   Tab池任务{task_id}: {tab.title}")
    
    with TabPool(max_tabs=12) as pool:
        threads = []
        for i, url in enumerate(urls):
            thread = threading.Thread(target=visit_with_pool, args=(pool, url, i+1))
            threads.append(thread)
            thread.start()
        
        for thread in threads:
            thread.join()
    
    pool_time = time.time() - start_time
    print(f"⏱️  Tab池方式耗时: {pool_time:.2f}秒")
    
    # 方式2: 传统顺序访问
    print("\n🐌 方式2: 传统顺序访问")
    start_time = time.time()
    
    co = ChromiumOptions()
    co.auto_port()
    from DrissionPage import Chromium
    browser = Chromium(co)
    tab = browser.get_tab()
    
    for i, url in enumerate(urls):
        tab.get(url)
        tab.wait.doc_loaded()
        print(f"   顺序任务{i+1}: {tab.title}")
    
    browser.quit()
    sequential_time = time.time() - start_time
    print(f"⏱️  顺序方式耗时: {sequential_time:.2f}秒")
    
    # 性能提升
    improvement = (sequential_time - pool_time) / sequential_time * 100
    print(f"\n📈 性能提升: {improvement:.1f}%")


def main():
    """主函数 - 运行所有示例"""
    print("🎯 TabPool 完整功能演示")
    print("包含7个示例，展示TabPool的各种功能和使用场景")
    
    examples = [
        ("基础用法", example1_basic_usage),
        ("并发任务", example2_concurrent_tasks),
        ("超时处理", example3_timeout_handling),
        ("自定义配置", example4_custom_browser_options),
        ("高级管理器", example5_tab_pool_manager),
        ("错误处理", example6_error_handling),
        ("性能对比", example7_performance_comparison),
    ]
    
    print("\n可用示例:")
    for i, (name, _) in enumerate(examples, 1):
        print(f"  {i}. {name}")
    print("  0. 运行所有示例")
    
    try:
        choice = input("\n请选择要运行的示例 (0-7): ").strip()
        
        if choice == '0':
            print("\n🚀 运行所有示例...")
            for name, func in examples:
                print(f"\n{'='*20} {name} {'='*20}")
                func()
                time.sleep(2)
        elif choice.isdigit() and 1 <= int(choice) <= len(examples):
            idx = int(choice) - 1
            name, func = examples[idx]
            print(f"\n🚀 运行示例: {name}")
            func()
        else:
            print("❌ 无效选择")
    
    except KeyboardInterrupt:
        print("\n\n👋 用户中断，程序退出")
    except Exception as e:
        print(f"\n❌ 运行出错: {e}")
    
    print("\n✨ 演示完成！")


if __name__ == "__main__":
    main()